package sy4_Creational_Pattern.builder.常用hlb;

/**
 * 建造者模式应用广泛。例如，在安卓中建造 Toast和 Notification
 * 实现产品的必选和灵活的任选
 * 要点：作为内部类、表示建造者的Builder的字段与外部类的字段相同。
 */

public class Computer { //产品类
    private final String cpu;//必须
    private final String ram;//内存，必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//显示器，可选

    public Computer(Builder builder){   //Computer依赖 Builder
        this.cpu=builder.cpu;
        this.ram=builder.ram;
        this.usbCount=builder.usbCount;
        this.keyboard=builder.keyboard;
        this.display=builder.display;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", usbCount=" + usbCount +
                ", keyboard='" + keyboard + '\'' +
                ", display='" + display + '\'' +
                '}';
    }

    public static class Builder{ //建造者：静态内部类，体现关联关系，其字段与Computer相同
        private String cpu;//必须
        private String ram;//必须

        private int usbCount;//任选
        private String keyboard;//任选
        private String display;//任选

        public Builder(String cpu,String ram){
            this.cpu=cpu;
            this.ram=ram;
        }

        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }
        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }
        public Builder setDisplay(String display) {
            this.display = display;

            return this;
        }

        public Computer build(){ //建造
            return new Computer(this);  //关键点：以this作为参数
        }
    }

    public static void main(String[] args) {
        //标准写法
        Builder builder = new Builder("因特尔", "三星");   //cpu和 ram为必选件
        builder.setDisplay("三星24寸").setKeyboard("罗技").setUsbCount(2);  //任选件
        Computer computer = builder.build();  //装配为完整产品
        //简便写法
        /*Computer computer = new Computer.Builder("因特尔", "三星")   //有参构造方法
                .setDisplay("三星24寸")  //任选
                .setKeyboard("罗技")   //任选
                .setUsbCount(2)  //任选
                .build();  //建造*/
        System.out.println(computer);
    }
}
